<template>
  <div class="toc-container" >
    <div class="toc-title">目录</div>
    <RightList :list="toWithSelect" @select="handleSelect" />
  </div>
</template>

<script>
import RightList from "./RightList";
import getArticle from "@/api/getArticle";
import debounce from "@/utils/debouce";
export default {
  data() {
    return {
      article: {},
      activeAnchor: "article-md-title-1",
    };
  },
  components: {
    RightList,
  },
  async created() {
    const resp = await getArticle();
    this.article = resp;
  },
  computed: {
    //将toc映射成具有isSelect属性的数组
    toWithSelect() {
      const getTOC = (toc = []) => {
        return toc.map((t) => ({
          ...t,
          active: t.anchor === this.activeAnchor,
          children: getTOC(t.children),
        }));
      };
      return getTOC(this.article.toc);
    },
    doms() {
      const doms = [];
      const addToDoms = (toc) => {
        for (const t of toc) {
          doms.push(document.getElementById(t.anchor));
          if (t.children && t.children.length) {
            addToDoms(t.children);
          }
        }
      };
      addToDoms(this.article.toc);
      return doms;
    },
  },
  async mounted() {
    document.addEventListener("scroll", () => {
      debounce(this.setSelect());
    });
  },
  methods: {
    handleSelect(item) {
      location.hash = item.anchor;
    },
    // 设置activeAnchor为正确的值
    setSelect() {
      this.activeAnchor = ""; // 由于后续要重新设置，先清空之前的状态
      const range = 200;
      for (const dom of this.doms) {
        // 看一下当前这个dom元素是不是应该被选中
        if (!dom) {
          continue;
        }
        // 得到元素离视口顶部的距离
        const top = dom.getBoundingClientRect().top;
        if (top >= 0 && top <= range) {
          // 在规定的范围内
          this.activeAnchor = dom.id;
          return;
        } else if (top > range) {
          // 在规定的范围下方
          return;
        } else {
          // 在规定的范围上方
          this.activeAnchor = dom.id; // 先假设自己是激活的，然后继续看后面
        }
      }
    },
  },
};
</script>

<style scoped lang="less">
.toc-container {
  position: sticky;
  top: 10px;
  background-color: #fff;
  border-radius: 4px;
  padding: 20px;
  .toc-title {
    font-weight: 500;
    padding-bottom: 10px;
    margin-bottom: 15px;
    font-size: 16px;
    line-height: 2rem;
    color: #1d2129;
    border-bottom: 1px solid #e4e6eb;
  }
}
</style>